﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Collections.ObjectModel;
using ARR.Entities;
using Telerik.Windows.Controls;
using ARR.UI.Models;
using ARR.Shared;
using ARR.UI.Commands;

namespace ARR.UI.ViewModels
{
    class TheoreticalMarginsViewModel : WorkspaceViewModel
    {
        private ITheoreticalMarginModel model;
        private ICommand categoryMarginsGV_SelectionChangedCommand;
        private ICommand articleMarginsGV_SelectionChangedCommand;
        private ICommand saveCommand;
        private ICommand cancelCommand;
        private ICommand deleteCommand;
        private bool isWindowedMode;



        public TheoreticalMarginsViewModel(ITheoreticalMarginModel model)
        {
            this.DisplayName = Labels.MargenesTeoricos;
            this.model = model;
            this.isWindowedMode = false;
        }

        public TheoreticalMarginsViewModel(IEnumerable<int> selectedIds, bool isCategories)
        {
            this.DisplayName = Labels.MargenesTeoricos;
            this.model = new TheoreticalMarginModel();
            this.isWindowedMode = true;

            if (isCategories)
            {
                LoadCategories(selectedIds);
            }
            else
            {
                LoadArticles(selectedIds);
            }
        }
        


        public ICommand CategoryMarginsGV_SelectionChangedCommand
        {
            get
            {
                if (categoryMarginsGV_SelectionChangedCommand == null)
                {
                    categoryMarginsGV_SelectionChangedCommand = new RelayCommand(e => CategoryMarginsGV_GetSelectedItems(e as SelectionChangeEventArgs));
                }
                return categoryMarginsGV_SelectionChangedCommand;
            }
        }

        public ICommand ArticleMarginsGV_SelectionChangedCommand
        {
            get
            {
                if (articleMarginsGV_SelectionChangedCommand == null)
                {
                    articleMarginsGV_SelectionChangedCommand = new RelayCommand(e => ArticleMarginsGV_GetSelectedItems(e as SelectionChangeEventArgs));
                }
                return articleMarginsGV_SelectionChangedCommand;
            }
        }

        public ICommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                {
                    saveCommand = new RelayCommand(e => Save());
                }
                return saveCommand;
            }
        }

        public ICommand CancelCommand
        {
            get
            {
                if (cancelCommand == null)
                {
                    cancelCommand = new RelayCommand(e => Cancel());
                }
                return cancelCommand;
            }
        }

        public ICommand DeleteCommand
        {
            get
            {
                if (deleteCommand == null)
                {
                    deleteCommand = new RelayCommand(e => Delete());
                }
                return deleteCommand;
            }
        }

        public ObservableCollection<Article> Articles
        {
            get
            {
                return model.Articles;
            }
        }

        public ObservableCollection<Category> Categories
        {
            get
            {
                return model.Categories;
            }
        }

        public ObservableCollection<TheoreticalMargin> TheoreticalMarginsForArticles
        {
            get
            {
                return model.TheoreticalMarginsForArticles;
            }
        }

        public ObservableCollection<TheoreticalMargin> TheoreticalMarginsForCategories
        {
            get
            {
                return model.TheoreticalMarginsForCategories;
            }
        }

        public List<TheoreticalMargin> SelectedTheoreticalMarginsForArticles { get; set; }

        public List<TheoreticalMargin> SelectedTheoreticalMarginsForCategories { get; set; }
        


        private void CategoryMarginsGV_GetSelectedItems(SelectionChangeEventArgs e)
        {
            try
            {
                List<TheoreticalMargin> added = e.AddedItems.Cast<TheoreticalMargin>().ToList();
                List<TheoreticalMargin> removed = e.RemovedItems.Cast<TheoreticalMargin>().ToList();

                SelectedTheoreticalMarginsForCategories.AddRange(added);
                removed.ForEach(at => SelectedTheoreticalMarginsForCategories.Remove(at));
            }
            catch
            {
            }
        }

        private void ArticleMarginsGV_GetSelectedItems(SelectionChangeEventArgs e)
        {
            try
            {
                List<TheoreticalMargin> added = e.AddedItems.Cast<TheoreticalMargin>().ToList();
                List<TheoreticalMargin> removed = e.RemovedItems.Cast<TheoreticalMargin>().ToList();

                SelectedTheoreticalMarginsForCategories.AddRange(added);
                removed.ForEach(at => SelectedTheoreticalMarginsForCategories.Remove(at));
            }
            catch
            {
            }
        }

        private void Save()
        {
            if (AreValid())
            {
                model.Save();

                if (isWindowedMode)
                {
                    Helpers.WindowManager.CloseView(this, true);
                }
                else
                {
                    model.LoadTheoreticalMargins();

                    OnPropertyChanged<TheoreticalMarginsViewModel>(p => p.TheoreticalMarginsForArticles);
                    OnPropertyChanged<TheoreticalMarginsViewModel>(p => p.TheoreticalMarginsForCategories);
                }
            }
        }

        private void Cancel()
        {
            if (isWindowedMode)
            {
                Helpers.WindowManager.CloseView(this, false);
            }
            else
            {
                model.LoadTheoreticalMargins();

                OnPropertyChanged<TheoreticalMarginsViewModel>(p => p.TheoreticalMarginsForArticles);
                OnPropertyChanged<TheoreticalMarginsViewModel>(p => p.TheoreticalMarginsForCategories);
            }
        }

        private void Delete()
        {

        }

        private bool AreValid()
        {
            foreach (TheoreticalMargin margin in TheoreticalMarginsForCategories.Union(TheoreticalMarginsForArticles))
            {
                if (!margin.IsValid)
                    return false;
            }

            return true;
        }

        private void LoadArticles(IEnumerable<int> selectedIds)
        {
            foreach (int id in selectedIds)
            {
                var art = model.Articles.SingleOrDefault(x => x.Id == id);

                var alreadyHasMargin = model.TheoreticalMarginsForArticles.Any(x => x.ArticleId == art.Id);

                if (!alreadyHasMargin)
                {
                    model.TheoreticalMarginsForArticles.Insert(0, new TheoreticalMargin
                    {
                        Article = art,
                        ArticleId = art.Id,
                        CountryId = WorkspaceData.Instance.Country.Id
                    });
                }
            }
        }

        private void LoadCategories(IEnumerable<int> selectedIds)
        {
            foreach (int id in selectedIds)
            {
                Category category = null;
                foreach (var cat in model.Categories)
                {
                    if (cat.Id == id)
                    {
                        category = cat; break;
                    }
                    else
                    {
                        foreach (var subcat in cat.SubCategories)
                        {
                            if (subcat.Id == id)
                            {
                                category = subcat; break;
                            }
                        }
                    }
                }

                model.TheoreticalMarginsForCategories.Insert(0, new TheoreticalMargin 
                { 
                    Category =  category, 
                    CategoryId = category.Id, 
                    CountryId = WorkspaceData.Instance.Country.Id
                });
            }
        }
    }
}
